#include <iostream>
#include <memory>
#include <vector>
#include <string>
#include <string>
#include <fstream>
#include <streambuf>
#include <sstream>
#include <cstdlib>
#include <new>
#include <typeinfo>
#include <list>
#include <thread> // std::thread
#include <mutex>  // std::mutex
#include <stdio.h>
#include <string.h>

using namespace std;

// 常用设计模式

17、观察者模式
观察者模式：定义对象间的一种一对多的依赖关系，当一个对象的状态发生改变时，所有依赖于它的对象都要得到通知并自动更新。

观察者模式从根本上讲必须包含两个角色：观察者和被观察对象。

被观察对象自身应该包含一个容器来存放观察者对象，当被观察者自身发生改变时通知容器内所有的观察者对象自动更新。

观察者对象可以注册到被观察者的中，完成注册后可以检测被观察者的变化，接收被观察者的通知。当然观察者也可以被注销掉，停止对被观察者的监控。


/*
* 关键代码：在目标类中增加一个ArrayList来存放观察者们。
*/
#include <iostream>
#include <list>
#include <memory>
​
using namespace std;
​
class View;
​
//被观察者抽象类   数据模型
class DataModel
{
public:
    virtual ~DataModel(){}
    virtual void addView(View* view) = 0;
    virtual void removeView(View* view) = 0;
    virtual void notify() = 0;   //通知函数
};
​
//观察者抽象类   视图
class View
{
public:
    virtual ~View(){ cout << "~View()" << endl; }
    virtual void update() = 0;
    virtual void setViewName(const string& name) = 0;
    virtual const string& name() = 0;
};
​
//具体的被观察类， 整数模型
class IntDataModel:public DataModel
{
public:
    ~IntDataModel()
    {
        m_pViewList.clear();
    }
​
    virtual void addView(View* view) override
    {
        shared_ptr<View> temp(view);
        auto iter = find(m_pViewList.begin(), m_pViewList.end(), temp);
        if(iter == m_pViewList.end())
        {
            m_pViewList.push_front(temp);
        }
        else
        {
            cout << "View already exists" << endl;
        }
    }
​
    void removeView(View* view) override
    {
        auto iter = m_pViewList.begin();
        for(; iter != m_pViewList.end(); iter++)
        {
            if((*iter).get() == view)
            {
                m_pViewList.erase(iter);
                cout << "remove view" << endl;
                return;
            }
        }
    }
​
    virtual void notify() override
    {
        auto iter = m_pViewList.begin();
        for(; iter != m_pViewList.end(); iter++)
        {
            (*iter).get()->update();
        }
    }
​
private:
    list<shared_ptr<View>> m_pViewList;
};
​
//具体的观察者类    表视图
class TableView : public View
{
public:
    TableView() : m_name("unknow"){}
    TableView(const string& name) : m_name(name){}
    ~TableView(){ cout << "~TableView(): " << m_name.data() << endl; }
​
    void setViewName(const string& name)
    {
        m_name = name;
    }
​
    const string& name()
    {
        return m_name;
    }
​
    void update() override
    {
        cout << m_name.data() << " update" << endl;
    }
​
private:
    string m_name;
};
​
int main()
{
    /*
    * 这里需要补充说明的是在此示例代码中，View一旦被注册到DataModel类之后，DataModel解析时会自动解析掉     * 内部容器中存储的View对象，因此注册后的View对象不需要在手动去delete，再去delete View对象会出错。
    */

    View* v1 = new TableView("TableView1");
    View* v2 = new TableView("TableView2");
    View* v3 = new TableView("TableView3");
    View* v4 = new TableView("TableView4");
​
    IntDataModel* model = new IntDataModel;
    model->addView(v1);
    model->addView(v2);
    model->addView(v3);
    model->addView(v4);
​
    model->notify();
​
    cout << "-------------\n" << endl;
​
    model->removeView(v1);
​
    model->notify();
​
    delete model;
    model = nullptr;
​
    return 0;
}
​